// 可选参数用[]表示 里面的参数使用了类型的话会报错，因为age需要是int类型，不传的话就默认是null了 这就是空安全
// 如果允许为空 需要使用? [int? age, int? gender] 或者使用默认值[int? age,int gender=0])
// 命名参数 {}可以代替[] printInfo(String name,String city,{int? age, int? gender=0}){}
//如果所有的参数都是命名参数（加了大括号的都会变成可选参数） 如何保证必填项呢 使用required ({required String name,required String city,int? age, int? gender=0})
//上面的函数调用时有两个命名必填参数 printInfo(name:'刘俊强',city:'北京');
// []和{}后面不能再有参数，会报错
// 箭头函数只能写一行 返回一个表达式 不需要处理this问题，为了少写代码更简洁
// 函数自执行和闭包和js 无差别
// 异步函数返回的是Future类型 Future bar() async{ return 'sdf';} 而不是String类型

import 'dart:ffi';
import 'dart:math';

import 'animal.dart';

printInfo(
    {required String name, required String city, int? age, int gender = 0}) {
  //
  print(name + city);
}

foo() async {
  String barstr = await bar();
  print(barstr);
}

Future bar() async {
  //
  return 'sdf';
}

main1() {
  printInfo(name: '刘俊强', city: '北京', age: 4, gender: 1);
  foo();
  // Animals animals = Animals(name:'小狗',food:'骨头',legs: 4);

  // // animals._legs = 4;
  // animals.eat();
  // animals.run();
  // Animals.jump();
  Dog dog = Dog();
  dog.run();
  dog.eat();
  // Animals animals = Animals() //连缀操作符
  //   ..name = '小狗'
  //   ..food = '骨头'
  //   ..eat();
}
// 变量
// main() {
//  var  const final（只能赋值一次的类型） 自动类型推断
// var num1=1;
// var num1=1.3;  报错 一开始赋值的值的类型就是定义的变量的类型
// final num2;
// num2=5;
// num2=7; 包错
// 使用类型赋值
// int num3=5;

// double num4=1.4;
// String str='3'; //3px 就会报错
// int num5=int.parse(str);
// print(num5);
// printInfo('liu','北京', 3,4);
// String str1 = 'Hellow';
// String str2 = 'World';
// String str3 = "$str1 $str2";
// String str4 = "${str1 + str3}'sfsdf' $str2";
// String str5 = '''dslgs
//   //多行文本实现
//   ''';
// print(str5);
//判断类型
// String str6='sgsdf';
// int num6=5;
// print(str6 is String);
// print(num6 is int);
// }

//数组 对象
// main() {
// var mylist = [1, 2, 3, 4, 5, '7', {}];
// List<int> mylist1 = [1, 2, 8, 8, 4, 5];
// mylist.add(3);
// mylist.addAll([3, 4, 5, 6]);
// mylist.addAll(mylist1); //数组拼接
// mylist.shuffle();   // 打乱数组
// mylist1.remove(8); //从数组删除第一个8  [1, 2, 8, 8，4, 5] => [1, 2, 8, 4, 5]
// mylist1.removeAt(0); //删除下标0的元素
// mylist1.setAll(2,[0,9,8]); //从2下标开始替换[1, 2, 0, 9, 8, 5] 没替换的位置会保留
// mylist1.retainWhere((element) => element%2==0); //保留  去掉奇数
// mylist1.removeWhere((element) => element%2==0); //删除  去掉偶数
// print(mylist.last);
// print(mylist.first);
// print(mylist1);
// List<int> mylist3 = [1, 2, 8, 8, 4, 5];
// List rList=mylist3.reversed.toList(growable: false); //不改变原数组  growable:true或者不加参数就是正常数组  growable:false返回一个不可增长的数组
// rList.add(3); //报错 Cannot add to a fixed-length list
// print('$rList $mylist3');
// List<int> mylist3 = [1, 2, 8, 8, 4, 5];
// List<int> mylist4=mylist3.take(3).toList(); //返回新数组
// print('$mylist3 $mylist4');
// List<int> mylist3 = [1, 2, 8, 8, 4, 5, 3];
// List<int> mylist4 = mylist3.take(3).toList(); //返回新数组
// List<int> mylist5 = mylist3
//     .takeWhile((value) => value < 4)
//     .toList(); //从第一个开始返回true的留下直到返回false就停止了 返回新数组[ 1, 2] 没有最后面的3
// print('$mylist3 $mylist4 $mylist5');
//  List<int> mylist3 = [1, 2, 8, 8, 4, 5, 3];
//  List<int>mylist4=mylist3.where((element) => element%2==0).toList();//从第一个开始返回 true的都留下  [2, 8, 8, 4]
//  print('$mylist3 $mylist4');
// List<int> mylist3 = [1, 2, 8, 8, 4, 5, 3];
// print(mylist3.every((element) => element > 2)); //  false 是不是所有元素都符合条件
// print(mylist3.any((element) => element == 5)); //  true 任意一个符合条件
//  List<int> mylist3 = [1, 2, 8, 8, 4, 5, 3];
//  print(mylist3.contains(2)); //true 是否包含某个元素
//  print(mylist3.firstWhere((element) => element>2)); //8 返回第一个符合的元素
//  mylist3.lastWhere((element) => false);  //从后往前 返回第一个符合的元素
//  mylist3.indexWhere((element) => false); //返回第一个符合的元素的index
//  mylist3.lastIndexWhere((element) => false);//从后往前 返回第一个符合的元素的index
//  List<int> myList4=[];
//  mylist3.forEach((element)=>myList4.add(element));
//  print(myList4);
// List<int> mylist3 = [1, 2, 8, 8, 4, 5, 3];
// Set myset = mylist3.toSet();
// String myString = mylist3.toString();
// Map mymap =mylist3.asMap(); // 数组转对象
// List mylist5=mylist3.toList(); //返回一个新数组
// mylist5[0]=99;
// print(mylist3);
// Map mymap={
//   'name':'刘俊强',
//   'city':'北京',
//   'age':34,
// };
//  Map mymap1={
//   'name':'liyang',
//   'city':'北京',
//   'age':34,
//   'show':'en'
// };
// mymap['gender']=1;
// mymap.addAll(mymap1);
// print(mymap); //{name: liyang, city: 北京, age: 34, gender: 1, show: en}
// Map mymap2={};
// mymap2.isEmpty; //true
// mymap2.isNotEmpty;//false
// }

// 构造函数
// operator +(Vector v){}  函数的参数指的都是符号后面的 比如 v + w 此时的w会传入函数中
// operator ==(Object other){}  函数的参数指的都是符号后面的 比如 v - w == Vector(-2, -2) 此时的Vector(-2, -2)的返回值会被传入函数
// class Vector {
//   final int x, y;
//   Vector(this.x, this.y);
//   Vector operator +(Vector v) {print(x); return Vector(x + v.x, y + v.y);}
//   Vector operator -(Vector v){print(x); return Vector(x - v.x, y -v.y);}

//   @override
//   bool operator ==(Object other) =>
//       other is Vector && x == other.x && y == other.y;

//   @override
//   int get hashCode => Object.hash(x, y);
// }

// void main() {
//   final v = Vector(1, 2);
//   final w = Vector(3, 4);

//   print(v + w ==  Vector(4, 6)); //1
//   print(v - w == Vector(-2, -2)); //1
// }

// class Rectangle {
//   double left, top, width, height;
//   Rectangle(this.left, this.top, this.width, this.height);
//   // Define two calculated properties: right and bottom.
//   double get right => left + width; // get 不需要带参数列表 right是属性名 换成普通函数 double get right {return left + width;}
//   set right(double value) => left = value - width;
//   double get bottom => top + height;   //  double get bottom => this.bottom; 写成这样会报错 Stack Overflow
//   set bottom(double value) => top = value - height;
// }

// void main() {
//   var rect = Rectangle(3, 4, 20, 15);
//   assert(rect.left == 3);
//   rect.right = 12;
//   assert(rect.left == -8);
// }

// extension type E(int i) {
//   E.fromString(String foo) : i = int.parse(foo);
// }
// main(){
//  var i= E(34);
//  print(i);
// }
//

int fun() {
  print(33333);
  return 4;
}

class po {
  static int aa1 = fun(); //po.aa1访问时候才会执行fun
  int aa = fun(); //po()调用时才会执行 po构造函数  但会在之前执行fun
  late int bb;
  po() {
    this.bb = 3;
    print(4444);
  }
}

extension type E(int i) {
  E.n(this.i);
  E.m(int j, String foo) : i = j + foo.length;
}
Future fstr() async {
  return 'fstr';
}

void main() {
  List list1 = [];
  List list2 = list1.toList();
  list2.add(3);
  print(list1);
  print(list2);
  print(list2 == list1);
  flu() async {}
  E(4); // Implicit unnamed constructor.
  E.n(3); // Named constructor.
  print(E.m(5, "Hello!").i); // Named constructor with additional parameters.
  var bool2 = 'sdf';
  fstr().then((_) {
    //似乎也存在微任务
    print(_);
  });
  fstr().then((_) {
    //似乎也存在微任务
    print('fstr2');
  });
  print('我是str');
  print(bool2 ?? 2);
  String timestamp = (DateTime.now().millisecondsSinceEpoch / 1000).toString();
  print(timestamp.substring(0, timestamp.length - 3));
  const a = const Point(1, 1);
  po.aa1;
  print(66);
}

// xcode sign
//com.example.flutterUnity12
